#ifndef INC_MODEL_FRAGMENT_LINK_BUILDER_H
#define INC_MODEL_FRAGMENT_LINK_BUILDER_H

#include "Fragment.h"
#include "ModelException.h"

#include <string>
#include <list>
#include <map>

class Atom_Link{};

class Link_Prototipe 
{
	public:
		const std::string get_atom1_fqn() const { return ""; };
		const std::string get_atom2_fqn() const { return ""; };
		const Atom_Link* new_link(const Atom* a1, const Atom* a2) const { return NULL; }
};

class FragmentLinkBuilder
{
	typedef std::string AA_Name; // TODO: Use this typedef from frag and all across the project
	typedef std::list< Link_Prototipe* > Link_Prototipes;
	typedef std::map< AA_Name, Link_Prototipes > Link_Protos_by_Fragment;
	Link_Protos_by_Fragment link_protos;

	public:
		void build_links(Fragment* frag) const
		{
			const Link_Prototipes& protos = link_protos.find( frag->get_name() )->second;

			if (protos.size() == 0)
				throw ModelException(("Fragment " + frag->get_name() + " has no linking rules defined.").c_str());

			for (Link_Prototipes::const_iterator i = protos.begin();
							i != protos.end(); ++i)
			{
				const Link_Prototipe* lp = *i;
				const std::string& atom1_fqn = lp->get_atom1_fqn();
				const std::string& atom2_fqn = lp->get_atom2_fqn();
				const Atom* atom1 = frag->locate( atom1_fqn );
				const Atom* atom2 = frag->locate( atom2_fqn );
				const Atom_Link* link = lp->new_link(atom1, atom2);
				// frag->add_link(link); molecule->add_link?
			}
		}
};


#endif /* INC_MODEL_FRAGMENT_LINK_BUILDER_H */
